package cn.yhbk.web.modules.manager.Service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.yhbk.web.common.exception.ApiException;
import cn.yhbk.web.modules.manager.Mapper.TbCounsellorClassMapper;
import cn.yhbk.web.modules.manager.Mapper.TbCounsellorMapper;
import cn.yhbk.web.modules.manager.Pojo.DTO.Student.StudentParamDTO;
import cn.yhbk.web.modules.manager.Pojo.Entity.TbClass;
import cn.yhbk.web.modules.manager.Pojo.Entity.TbStudent;
import cn.yhbk.web.modules.manager.Mapper.TbStudentMapper;
import cn.yhbk.web.modules.manager.Pojo.VO.Student.StudentAdd;
import cn.yhbk.web.modules.manager.Service.IFlagService;
import cn.yhbk.web.modules.manager.Service.IOrderResultItemService;
import cn.yhbk.web.modules.manager.Service.ITbClassService;
import cn.yhbk.web.modules.manager.Service.ITbStudentService;
import cn.yhbk.web.modules.ums.dto.UmsAdminParam;
import cn.yhbk.web.modules.ums.model.UmsAdmin;
import cn.yhbk.web.modules.ums.service.UmsAdminService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 学生表 服务实现类
 * </p>
 *
 * @author 有何不可
 * @since 2023-08-05
 */
@Service
@Slf4j
public class TbStudentServiceImpl extends ServiceImpl<TbStudentMapper, TbStudent> implements ITbStudentService {

    @Autowired
    private UmsAdminService adminService;

    @Autowired
    private IFlagService flagService;

    @Autowired
    private TbCounsellorClassMapper counsellorClassMapper;

    @Autowired
    private ITbClassService classService;

    @Autowired
    private TbStudentMapper studentMapper;

    @Autowired
    private TbCounsellorMapper counsellorMapper;

    @Autowired
    private IOrderResultItemService itemService;

    @Override
    @Transactional
    public boolean add(StudentAdd studentAdd) {

        //先添加账号
        UmsAdminParam umsAdminParam = new UmsAdminParam();
        umsAdminParam.setUsername(studentAdd.getJobNumber());
        umsAdminParam.setPassword(studentAdd.getPassword());
        UmsAdmin register = adminService.register(umsAdminParam);
        if(Objects.isNull(register)){
            log.error("添加账号失败");
            throw new ApiException("添加失败!");
        }
        Long adminId = register.getId();



        //添加用户信息
        TbStudent student = new TbStudent();
        BeanUtil.copyProperties(studentAdd,student);
        student.setAdminId(adminId);
//        //设置冗余字段辅导员
//        TbClass tbClass = classService.getById(student.getClassId());
//
//        if(Objects.isNull(tbClass) || Objects.isNull(tbClass.getCounsellorId())){
//            log.error("添加学生时设置辅导员失败!");
//            throw new ApiException("添加失败!");
//        }
//        student.setCounsellorId(tbClass.getCounsellorId());

        boolean save = save(student);
        if(!save){
            log.error("添加信息失败!");
            throw new ApiException("添加失败!");
        }


        //设置角色
        Long studentRoleId = flagService.getStudentRoleId();
        int updateRole = adminService.updateRole(adminId, Collections.singletonList(studentRoleId));
        if(updateRole == 0){
            log.error("设置角色失败!");
            throw new ApiException("添加失败!");
        }

        //给班级添加人数
        new Thread(()->{
            classService.operatePopulation(1,student.getClassId());
        }).start();


        return true;
    }

    @Override
    public TbStudent getStudentByAdminId(Long adminId) {
        QueryWrapper<TbStudent> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<TbStudent> lambda = wrapper.lambda();

        lambda.eq(TbStudent::getAdminId,adminId);
        return getOne(lambda);
    }

    @Override
    public Page<TbStudent> getStudent(Long currentPage, Long pageSize, StudentParamDTO condition) {
        Page<TbStudent> page = new Page<>(currentPage,pageSize);

        QueryWrapper<TbStudent> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<TbStudent> lambda = wrapper.lambda();

        Long id = condition.getId();
        if(!Objects.isNull(id))lambda.eq(TbStudent::getId,id);

        String sname = condition.getName();
        if(!Strings.isBlank(sname))lambda.like(TbStudent::getName,sname);

        String sno = condition.getJobNumber();
        if(!Strings.isBlank(sno))lambda.like(TbStudent::getJobNumber,sno);

        String idCard = condition.getIdCard();
        if(!Strings.isBlank(idCard))lambda.like(TbStudent::getIdCard,idCard);

        Long classId = condition.getClassId();
        if(!Objects.isNull(classId))lambda.eq(TbStudent::getClassId,classId);

        String phone = condition.getPhone();
        if(!Strings.isBlank(phone))lambda.like(TbStudent::getPhone,phone);

        Byte status = condition.getStatus();
        if(!Objects.isNull(status))lambda.eq(TbStudent::getStatus,status);

        Boolean gender = condition.getGender();
        if(!Objects.isNull(gender))lambda.eq(TbStudent::getGender,gender);

        List<Long> adminIds = condition.getAdminIds();
        if(!Objects.isNull(adminIds) && !adminIds.isEmpty())lambda.in(TbStudent::getAdminId,adminIds);

        lambda.orderByDesc(TbStudent::getClassId);

        Page<TbStudent> dataPage = page(page, lambda);
        return dataPage;
    }

    @Override
    @Transactional
    public boolean removeStudent(Long studentId) {

        TbStudent student = getById(studentId);
        if(Objects.isNull(student))return false;
        //删除账号
        Long adminId = student.getAdminId();
        boolean delete = adminService.delete(adminId);
        if(!delete){
            log.error("删除账号失败!");
            throw new ApiException("删除失败!");
        }
        //删除学生信息
        boolean remove = removeById(studentId);
        if(!remove){
            log.error("删除学生信息失败!");
            throw new ApiException("删除失败!");
        }

        //更新人数
        new Thread(()->{
            classService.operatePopulation(-1,student.getClassId());
        }).start();

        return true;
    }

    @Override
    public Long getStudentIdByAdminId(Long adminId) {
        QueryWrapper<TbStudent> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<TbStudent> lambda = wrapper.lambda();

        lambda.eq(TbStudent::getAdminId,adminId);
        TbStudent student = getOne(lambda);
        if(Objects.isNull(student)){
            log.error("根据admin查询到得student为空");
            throw new ApiException("添加失败!请联系管理员");
        }
        return student.getId();
    }

    @Override
    public int populationForClass(Long classId) {
        return studentMapper.populationForClass(classId);
    }

    @Override
    public List<Long> getStudentIdByCounsellorId(Long counsellorId) {
        return  counsellorMapper.getStudentIdByCounsellorId(counsellorId);
    }

    @Override
    public boolean checkStudentByCounsellor(Long counsellorId, Long stuId) {
        QueryWrapper<TbStudent> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<TbStudent> lambda = wrapper.lambda();

        lambda.eq(TbStudent::getId, stuId);
        lambda.eq(TbStudent::getCounsellorId,counsellorId);

        TbStudent one = getOne(lambda);
        return !Objects.isNull(one);
    }

    @Override
    public List<Long> getStudentIdByClassId(Long classId) {
        return studentMapper.getStudentIdByClassId(classId);
    }

    @Override
    public List<Long> getStudentIdsByClassIds(List<Long> classIds) {
        if(classIds.isEmpty())return new ArrayList<>();

        LambdaQueryWrapper<TbStudent> lambda = new QueryWrapper<TbStudent>().lambda();
        lambda.in(TbStudent::getClassId,classIds);
        List<TbStudent> list = list(lambda);
        return list.stream().map(TbStudent::getId).filter(item->!Objects.isNull(item)).distinct().collect(Collectors.toList());

    }

    @Override
    public boolean checkStudentByClassId(Long classId, Long stuId) {
        QueryWrapper<TbStudent> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<TbStudent> lambda = wrapper.lambda();

        lambda.eq(TbStudent::getClassId,classId);
        lambda.eq(TbStudent::getId,stuId);

        TbStudent one = getOne(lambda);
        return !Objects.isNull(one);
    }

    @Override
    public void updateCounsellorIdByClassId(Long counsellorId, List<Long> classIds) {
        this.baseMapper.updateCounsellorIdByClassId(counsellorId, classIds);
    }

    @Override
    public List<Long> getStuIdsByResultId(Long resultId) {

        List<Long> classIds = itemService.packageResultByResultId(resultId);
        List<Long> stuIds = getStudentIdsByClassIds(classIds);
        if(stuIds.isEmpty())throw new ApiException("集合学生为空!");
        return stuIds;

    }
}
